package com.wdy.config;

import com.wdy.filter.TokenAuthFilter;
import com.wdy.filter.TokenLoginFilter;
import com.wdy.ssafe.TokenLogoutHandeler;
import com.wdy.ssafe.TokenManager;
import com.wdy.ssafe.UnAuthEntryPoint;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;

@SpringBootConfiguration
public class TokenWebSecurityConfig extends WebSecurityConfigurerAdapter {

  @Autowired
  private TokenManager tokenManager;

  @Autowired
  private RedisTemplate<String, Object> redisTemplate;

  @Autowired
  private UserDetailsService userDetailsService;

  @Autowired
  private PasswordEncoder passwordEncoder;

  /**
   * 配置设置
   *
   * @param http
   * @throws Exception
   */
  //设置退出的地址和token，redis操作地址
  @Override
  protected void configure(HttpSecurity http) throws Exception {
    http.exceptionHandling()
        .authenticationEntryPoint(new UnAuthEntryPoint())//没有权限访问
        .and().csrf().disable()
        .authorizeRequests()
        .anyRequest().authenticated()
        .and().logout().logoutUrl("/admin/acl/index/logout")//退出路径
        .addLogoutHandler(new TokenLogoutHandeler(this.redisTemplate, this.tokenManager)).and()
        .addFilter(
            new TokenLoginFilter(authenticationManager(), this.tokenManager, this.redisTemplate))
        .addFilter(
            new TokenAuthFilter(authenticationManager(), this.tokenManager, this.redisTemplate))
        .httpBasic();
  }

  //调用userDetailsService和密码处理
  @Override
  public void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder);
  }

  //不进行认证的路径，可以直接访问
  @Override
  public void configure(WebSecurity web) throws Exception {
    web.ignoring().antMatchers("/api/**");
  }
}
